#pragma once
//这个文件将进行线程封装的初始版本
#include<iostream>
#include<string>
#include<cstring>
#include<pthread.h>
#include<unistd.h>
#include <functional>

namespace ThreadModle
{
    static uint32_t number = 1; //为了写线程的名字，一个一个的写
    class Thread
    {
        static void* Routine(void* argc)  //类内的成员函数必须是static的，因为static函数修饰的成员函数是没有this指针的
        {
            Thread* self = static_cast<Thread*>(argc);
            self ->Running();
            if(self->_isdeatch)
            {}; //等会写完了分离再说
            pthread_setname_np(self -> _tid,self->_name.c_str());  //把它放到了线程的局部空间里面
            self -> _func();  //调用自己传入的函数了 ,别忘记括号，nnd忘掉了
            return nullptr;
        }
        void Running()
        {
            _running = true;  //让新线程开始运行起来
        }
        void EnableDeatch()
        {
            std :: cout << "线程成功的被分离了" << std :: endl;
            _isdeatch = true; //让新线程变为分离态
        }
        using func_t = std::function<void()>; // 暂时这样写，完全够了
    public:
        Thread(func_t func) : _func(func)
        ,_tid(0),
        // _name(nullptr),
        _isdeatch(false),
        _running(false),
        res(nullptr)
        {
            _name = "thread-" + std::to_string(number++);
        }
        bool Start()  //现成的建立，并且将它跑起来
        {
            if(_running)  //这个条件是避免多次进行start的，md一感冒脑子直接瓦特了，就这破玩意我还想了半天，我真的该死
            return false;
            int n = pthread_create(&_tid,nullptr,Routine,(void*)this);
            if(n > 0)
            {
                std :: cerr << "pthread_creart false" << std :: endl;
                return false;
            }
            else if(n == 0)
            {
                std :: cout << "线程创建成功" << std :: endl;
            }
            return true;
        }

        bool Deatch()
        {
            if(_isdeatch)  //如果本来就分离了，那么不用重复分离了
            return false;
            if(_running)
            {
                pthread_detach(_tid);
            }
            EnableDeatch();  //表明此时进入了分离太
            return true;
        }


        bool Stop()
        {
            if(_running)  //确保现在此时线程正在跑着，不然还没跑暂停个der
            {
                int n = pthread_cancel(_tid); 
                if(n != 0)
                {
                    std :: cerr << "pthread_cancel false" << std :: endl;
                    return false;
                }
                else
                {
                    _running = false; //暂停了，所以跑不起来了
                    std :: cout << "线程暂停成功"  << "，名字是：" << _name << std :: endl;
                    return true;
                }
                return false;
            }
        }

        void Join()
        {
            if(_isdeatch) return; //都分离了，你还等待啥
            int n = pthread_join(_tid,&res);
            if(n == 0)
            {
                std :: cout << "叮咚！  线程等待成功" << std :: endl;
            }
            else
            {
                std :: cout << "On No~   线程等待失败" << std :: endl;
            }
        }
        ~Thread(){}
    private:
        pthread_t _tid;
        std :: string _name; //保存线程的名字
        bool _isdeatch; //判断是不是分离状态的
        bool _running; //判断此时的线程是否在运行中
        void* res; //等待时退出返回的值，可以是空，也可以是自己相要写的信息
        func_t _func;  //函数指针
    };
}